package com.ctit.jbpm.bo;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Session;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.graph.def.ProcessDefinition;

 

import com.ctit.jbpm.vo.*;

public class ProcessBoImpl extends AbstractBo implements ProcessBo {

	Logger log = Logger.getLogger(ProcessBoImpl.class);

	

	/**
	 * 部署工作流
	 */
	public void deployProcessDefinition(String xml, String schema)
			throws Exception {
		JbpmContext jbpmContext = null;
		try {
			jbpmContext = this.getJbpmContext();
			ProcessDefinition pd = ProcessDefinition.parseXmlString(xml);
			jbpmContext.deployProcessDefinition(pd);
			if (xml.indexOf("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") > -1)
				xml = xml.replaceAll("encoding=\\\"UTF-8\\\"",
						"encoding=\\\"GBK\\\"");
			else
				xml = "<?xml version=\"1.0\" encoding=\"GBK\"?>" + xml;
			this.saveProcessDefinitionInfo(xml, schema, (int) pd.getId());
		} catch (Exception e) {
			jbpmContext.setRollbackOnly();
			throw e;
		} finally {
			jbpmContext.close();
		}
	}

	/**
	 * 列出所有的工作流
	 */
	public List<ProcessDefinition> findAllProcessDefinition() throws Exception {
		JbpmContext jbpmContext = null;
		List<ProcessDefinition> procDefs = null;
		try {
			jbpmContext = this.getJbpmContext();
			procDefs = jbpmContext.getGraphSession()
					.findLatestProcessDefinitions();
		} catch (Exception e) {
			throw e;
		} finally {
			jbpmContext.close();
		}
		return procDefs;
	}

	/**
	 * 根据ID查询工作流
	 */
	public ProcessDefinition findProcessDefinitionById(long procId)
			throws Exception {
		JbpmContext jbpmContext = null;
		ProcessDefinition procDef = null;
		try {
			jbpmContext = this.getJbpmContext();
			procDef = jbpmContext.getGraphSession()
					.getProcessDefinition(procId);
		} catch (Exception e) {
			throw e;
		} finally {
			jbpmContext.close();
		}
		return procDef;
	}

	/**
	 * 根据ID删除工作流
	 */
	public void deleteProcessDefinitionById(long procId) throws Exception {
		JbpmContext jbpmContext = null;
		try {
			jbpmContext = this.getJbpmContext();
			jbpmContext.getGraphSession().deleteProcessDefinition(procId);
			deleteProcessDefinitionInfo((int) procId);
		} catch (Exception e) {
			jbpmContext.setRollbackOnly();
			throw e;
		} finally {
			jbpmContext.close();
		}
	}


  /**
   * 根据ID查询工作流的xml和schema信息
   */
  public ProcessDefinitionInfo findProcessDefinitionInfoByProcId(
      long procDefId) throws Exception {
    return findProcessDefinitionInfo(procDefId);
  }

	/**
	 * 保存指定的工作流的xml和schema信息
	 * 
	 * @param xml
	 * @param schema
	 * @param procId
	 * @throws Exception
	 */
	private void saveProcessDefinitionInfo(String xml, String schema,
			long procDefId) throws Exception {
		JbpmConfiguration configuration = null;
		JbpmContext jbpmContext = null;
		Session hSession = null;
		Connection conn = null;
		PreparedStatement pstmt = null;
		try {
			configuration = JbpmConfiguration.getInstance();
			jbpmContext = configuration.createJbpmContext();
			hSession = jbpmContext.getSession();
			conn = hSession.connection();
			String sql = "INSERT INTO jbpm_processdefinitioninfo(XML_,SCHEMA_,PROCID_) VALUES(?,?,?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, xml);
			pstmt.setString(2, schema);
			pstmt.setInt(3, (int) procDefId);
			pstmt.execute();
		} catch (Exception e) {
			conn.rollback();
			throw e;
		} finally {
			pstmt.close();
			jbpmContext.close();
		}
	}

	/**
	 * 删除指定的工作流的xml和schema信息
	 * 
	 * @param procId
	 * @throws Exception
	 */
	private void deleteProcessDefinitionInfo(int procDefId) throws Exception {
		JbpmConfiguration configuration = null;
		JbpmContext jbpmContext = null;
		Session hSession = null;
		Connection conn = null;
		PreparedStatement pstmt = null;
		try {
			String sql = "DELETE FROM jbpm_processdefinitioninfo WHERE PROCID_="
					+ procDefId;
			configuration = JbpmConfiguration.getInstance();
			configuration = JbpmConfiguration.getInstance();
			jbpmContext = configuration.createJbpmContext();
			hSession = jbpmContext.getSession();
			conn = hSession.connection();
			pstmt = conn.prepareStatement(sql);
			pstmt.executeUpdate();
		} catch (Exception e) {
			conn.rollback();
			throw e;
		} finally {
			pstmt.close();
			jbpmContext.close();
		}
	}

	/**
	 * 根据ID查询工作流的xml和schema信息
	 * 
	 * @param procId
	 * @return
	 * @throws Exception
	 */
	private ProcessDefinitionInfo findProcessDefinitionInfo(long procDefId)
			throws Exception {
		JbpmConfiguration configuration = null;
		JbpmContext jbpmContext = null;
		Session hSession = null;
		Connection conn = null;
		PreparedStatement pstmt = null;
		ProcessDefinitionInfo procDefInfo = null;
		try {
			String sql = "SELECT xml_,schema_ FROM jbpm_processdefinitioninfo WHERE procid_="
					+ procDefId;
			configuration = JbpmConfiguration.getInstance();
			jbpmContext = configuration.createJbpmContext();
			hSession = jbpmContext.getSession();
			conn = hSession.connection();
			pstmt = conn.prepareStatement(sql);
			ResultSet rs = pstmt.executeQuery();
			procDefInfo = new ProcessDefinitionInfo();
			while (rs.next()) {
				String xml = rs.getString(1);
				String schema = rs.getString(2);
				procDefInfo.setXml(xml);
				procDefInfo.setSchema(schema);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			pstmt.close();
			jbpmContext.close();
		}
		return procDefInfo;
	}

	/**
	 * 模糊查询工作流
	 */
	public List<ProcessDefinition> findProcessDefinitionByPartOfName(String name)
			throws Exception {
		// JbpmConfiguration configuration = null;
		// JbpmContext jbpmContext = null;
		// Session hSession = null;
		// Connection conn = null;
		// PreparedStatement pstmt = null;
		// List<ProcessDefinition> procDefs = null;
		// try{
		// String sql = "SELECT * FROM jbpm_processdefinition WHERE name_ like
		// '%"+name+"%'";
		// configuration = JbpmConfiguration.getInstance();
		// jbpmContext = configuration.createJbpmContext();
		// hSession = jbpmContext.getSession();
		// conn = hSession.connection();
		// pstmt = conn.prepareStatement(sql);
		// ResultSet rs = pstmt.executeQuery();
		// procDefs = new ArrayList<ProcessDefinition>();
		// while(rs.next()){
		// ProcessDefinition procDef = new ProcessDefinition();
		// procDef.
		// procDef.setName(rs.getString(2));
		// procDef.setVersion(rs.getInt(3));
		// procDefs.add(procDef);
		// }
		// } catch (Exception e) {
		// throw e;
		// } finally {
		// pstmt.close();
		// jbpmContext.close();
		// }
		// return procDefs;
		List<ProcessDefinition> allProcDefs = this.findAllProcessDefinition();
		List<ProcessDefinition> procDefs = new ArrayList<ProcessDefinition>();
		for (ProcessDefinition p : allProcDefs) {
			if (p.getName().indexOf(name) != -1) {
				procDefs.add(p);
			}
		}
		return procDefs;
	}

	/**
	 * 根据工作流名字查询出该工作流所有的历史版本
	 */
	public List<ProcessDefinition> findProcessAllVersions(String procName)
			throws Exception {
		JbpmContext jbpmContext = null;
		List<ProcessDefinition> procDefs = null;
		try {
			jbpmContext = this.getJbpmContext();
			procDefs = jbpmContext.getGraphSession()
					.findAllProcessDefinitionVersions(procName);
		} catch (Exception e) {
			throw e;
		} finally {
			jbpmContext.close();
		}
		return procDefs;
	}

	
	
	public ProcessDefinition findProcessDefinitionByName(String procName)
			throws Exception {
		ProcessDefinition procDef = null;
		JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
		try{
			procDef = jbpmContext.getGraphSession().findLatestProcessDefinition(procName);
		} catch (Exception e) {
			throw e;
		} finally {
			jbpmContext.close();
		}
		return procDef;
	}

	public List<ProcessDefinition> findProcessDefinitionByNames(List<String> procNames)
			throws Exception {
		List<ProcessDefinition> procDefs = new ArrayList<ProcessDefinition>();
		JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
		try{
			for(String procName : procNames){
				ProcessDefinition procDef = jbpmContext.getGraphSession().findLatestProcessDefinition(procName);
				System.out.println(procDef);
				procDefs.add(procDef);
			}
		} catch (Exception e) {
			throw e;
		} finally {
			jbpmContext.close();
		}
		return procDefs;
	}

	public List<ProcessDefinition> findDepartmentProcessDefinitionByPartOfName(List<String> procNames,
			String name) throws Exception {
		List<ProcessDefinition> allProcDefs = this.findProcessDefinitionByNames(procNames);
		List<ProcessDefinition> procDefs = new ArrayList<ProcessDefinition>();
		for (ProcessDefinition p : allProcDefs) {
			if (p.getName().indexOf(name) != -1) {
				procDefs.add(p);
			}
		}
		return procDefs;
	}



}
